package com.jt.www.admin.order_pc.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.jt.www.admin.caseinfo.service.CaseInfoService;
import com.jt.www.admin.order_pc.service.ApplicationFormService;
import com.jt.www.admin.order_pc.service.ExtendService;
import com.jt.www.biz.order_pc.service.PreviewService;
import com.jt.www.common.service.PolicyAttributeService;
import com.jt.www.dao.mapper.application.ApplicationFileInfoMapper;
import com.jt.www.dao.mapper.endorse.EndorseMapper;
import com.jt.www.dao.mapper.issue.mapper.IssueListenerEntityMapper;
import com.jt.www.dao.mapper.risk.RiskInfoMapper;
import com.jt.www.dao.mapper.woxuebao.PayRecordEntityMapper;
import com.jt.www.domain.enums.common.CategoryEnum;
import com.jt.www.domain.enums.common.parser.ReturnType;
import com.jt.www.domain.enums.common.parser.SaveType;
import com.jt.www.domain.po.ApplicationFileInfoEntity;
import com.jt.www.domain.qo.EbaoPolicyQO;
import com.jt.www.domain.vo.EbaoPolicyVO;
import com.jt.www.domain.vo.EduPolicyBean;
import com.jt.www.domain.vo.EduPolicyVO;
import com.jt.www.enums.endorse.PolicyTypeEnum;
import com.jt.www.enums.extend.ExcelDownFileEnum;
import com.jt.www.enums.extend.ProgrameBasicPremEnum;
import com.jt.www.enums.extend.SchoolTypeEnum;
import com.jt.www.enums.issue.AppStatusEnum;
import com.jt.www.enums.issue.IssueCodeEnum;
import com.jt.www.exception.BizException;
import com.jt.www.exception.ParamException;
import com.jt.www.model.Insurancedata.MyPageInfo;
import com.jt.www.model.entity.risk.RiskInfoEntity;
import com.jt.www.model.issue.InsuranceCompanyVO;
import com.jt.www.model.issue.entity.IssueListenEntity;
import com.jt.www.model.mail.vo.AccountVo;
import com.jt.www.model.mail.vo.JtBranchAccountVo;
import com.jt.www.model.param.endorse.AppDetailProParam;
import com.jt.www.model.policyattribute.vo.PlicyClassVO;
import com.jt.www.model.remote.ins.CommonExtendVo;
import com.jt.www.model.remote.ins.EduExtendVO;
import com.jt.www.model.remote.ins.EduPolicyStatisticsVo;
import com.jt.www.model.remote.ins.InsManagerResultVO;
import com.jt.www.model.remote.user.EduAuthenInfoDetails;
import com.jt.www.model.reps.GenericDataResponse;
import com.jt.www.model.reps.GenericListResponse;
import com.jt.www.model.reps.GenericResponse;
import com.jt.www.model.reps.ResponseData;
import com.jt.www.model.vo.*;
import com.jt.www.model.vo.endorse.AppDetailProVo;
import com.jt.www.model.vo.endorse.DetailVo;
import com.jt.www.model.vo.sdCheck.*;
import com.jt.www.model.vo.woxuebao.OrgElementVO;
import com.jt.www.model.woxuebao.PayRecordEntity;
import com.jt.www.remote.ParserClient;
import com.jt.www.remote.PolClient;
import com.jt.www.remote.UserClient;
import com.jt.www.remote.ins.InsClient;
import com.jt.www.remote.woxuebao.InsOrderClient;
import com.jt.www.util.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ProjectName: edu-service
 * @Package: com.jt.www.service.application
 * @ClassName: ApplicatonFormServiceImpl
 * @Author: shalongteng
 * @Description: ${description}
 * @Date: 2019-06-19 14:45
 * @Version: 1.0
 */
@Service
public class ApplicatonFormServiceImpl implements ApplicationFormService {

    public static final Logger log = LoggerFactory.getLogger(ApplicatonFormServiceImpl.class);


    private static final int DEFUALT_QUERY_NUM = 1000;
    private static final String ORDER_BY_ID = "`id` desc";
    private static final String IS_DELETED = "isDeleted";
    private static final String PRODUCT_CODE = "productCode";
    /**
     * 出单补录清单解析modelCode
     */
    private static final String POST_RECORDED_MODEL_CODE = "xxcdbl";
    private static final String CHANNEL_CODE = "edu";
    //初始化山東地區,山東其他地市需要增加編碼
    private final static List SD_LIST = Arrays.asList(ExcelDownFileEnum.EDU_SD.getProductCode().split(","));// 获取山东所有产品编码
    //机构类型
    private final static String CORPORATION_ENT = "edu_02";
    //ebao业务分类编码  A0303-教育
    private final static String BUS_TYPE_1_CODE = "A03";
    private final static String BUS_TYPE_2_CODE = "A0303";
    @Autowired
    PayRecordEntityMapper payRecordEntityMapper;
    @Autowired
    RiskInfoMapper riskInfoMapper;
    @Autowired
    PreviewService previewService;
    @Autowired
    CaseInfoService caseInfoService;
    @Autowired
    ExtendService extendService;
    @Autowired
    private UserClient userClient;
    @Autowired
    private InsClient insClient;
    @Autowired
    private PolClient polClient;
    @Autowired
    private ParserClient parserClient;
    @Autowired
    private EndorseMapper endorseMapper;
    @Autowired
    private InsOrderClient insOrderClient;
    @Autowired
    private TemplateEngine templateEngine;
    @Autowired
    private IssueListenerEntityMapper issueListenerEntityMapper;
    @Autowired
    private ApplicationFileInfoMapper applicationFileInfoMapper;
    @Autowired
    private PolicyAttributeService policyAttributeService;

    /**
     * @Description: 查询投保单列表
     * @Param: applicationFormVo
     * @return: InsResultVO
     * @Author: shalongteng
     * @Date: 2019-06-19
     */
    @Override
    public ResponseData findApplicationForm(InsManagerQo insManagerQo, String findCode, boolean isDown) throws Exception {
        //添加用户查询权限
        boolean addUserSuccess = findApplicationFormAddUserInfo(insManagerQo, findCode);
        //如果不成功返回空列表
        if (!addUserSuccess) {
            ResponseData responseData = new ResponseData();
            responseData.setCode(GenericResponse.CODE_OK);
            responseData.setList(null);
            responseData.setMsg("未查询到投保单信息");
            responseData.setData(null);
            responseData.setTotal(0);

            return responseData;
        }
        //查询列表
        return findApplicationFormHasUserInfo(insManagerQo, findCode, isDown);
    }

    @Override
    public boolean findApplicationFormAddUserInfo(InsManagerQo insManagerQo, String findCode) throws Exception {
        log.debug(findCode + "前端传递参数 ，{}", JSON.toJSONString(insManagerQo));
        //请求用户中心
        ResponseEntity<GenericDataResponse<Map<String, Object>>> responseEntity = userClient.queryUserRoleAndAuthority(insManagerQo.getUserCode(), "sys_edu_man");
        LinkedHashMap<String, String> map = (LinkedHashMap) responseEntity.getBody().getData().get("dataPopedom");
        String jtBranchs = map.get("jtBranchs");
        //获取区域码, 可能是城市码,省编码,  多个值是以逗号隔开
        String dataArea = map.get("dataArea");

        log.debug(findCode + "用户中心返回值 jtBranchs = {}", jtBranchs);
        //错误的管理员
        if (StringUtils.isEmpty(insManagerQo.getLevel())) {
            log.error("用户等级level不能为空");
            return false;
        }
        if (StringUtils.isBlank(jtBranchs)) {
            //返回一个空的集合
            return false;
        }
        log.debug(findCode + "用户中心返回值 dataArea = {}", dataArea);
        //若jtBranchs为JT0000  则表示全国   jtBranchs不用传递
        if (StringUtils.equals("04", insManagerQo.getLevel()) && !"000000".equals(jtBranchs) || !StringUtils.equals("04", insManagerQo.getLevel()) && !"000000".equals(jtBranchs)) {//进入分支机构
            //查询管理务端保单

            if ("02".equals(insManagerQo.getChannelType()) || "02,0001".equals(insManagerQo.getChannelType())) {
                Map<String, Object> areaMap = setProAndCityCode(dataArea);
                insManagerQo.setProvinceCode(areaMap.get("province") != null ? areaMap.get("province").toString() : "");
                // 首先判断前端是否传入市编码查询条件，如果有，优先使用，如果没有，使用该账户配置的地市编码
                if (StringUtils.isNotBlank(insManagerQo.getCityCode())) {
                    insManagerQo.setCityCode(insManagerQo.getCityCode());
                } else {
                    insManagerQo.setCityCode(areaMap.get("city") != null ? areaMap.get("city").toString() : "");
                }
            } else if ("00".equals(insManagerQo.getChannelType())) {
                insManagerQo.setBranchScope(jtBranchs);
            }

        }
        insManagerQo.setUserCode(null);
        return true;
    }

    @Override
    public ResponseData findApplicationFormHasUserInfo(InsManagerQo insManagerQo, String findCode, boolean isDown) throws Exception {
        if ("00".equals(insManagerQo.getChannelType())) {//00-教保
            if (StringUtils.isNotEmpty(insManagerQo.getStudentTeacherName()) || StringUtils.isNotEmpty(insManagerQo.getStudentTeacherCardNo())) {

                List<String> appCodeList = endorseMapper.selectEndorseByNameAndCardNo(insManagerQo.getStudentTeacherName(), insManagerQo.getStudentTeacherCardNo());

                if (appCodeList.size() <= 0) {

                    ResponseData responseData = new ResponseData();
                    responseData.setCode(GenericResponse.CODE_OK);
                    responseData.setList(null);
                    responseData.setMsg("根据学生/教师姓名或证件号码未查询到投保单信息");
                    responseData.setData(null);
                    responseData.setTotal(0);

                    return responseData;
                }
                insManagerQo.setAppCodes(appCodeList);
            }
        } else if ("02".equals(insManagerQo.getChannelType()) || "02,0001".equals(insManagerQo.getChannelType())) {//02我学保

            //管理端我学保保单列表增加商户订单号入参逻辑
            if (StringUtils.isNotBlank(insManagerQo.getTradeNo())) {
                Map<String, Object> result = setTradeNoParam(insManagerQo);
                boolean isExists = (boolean) result.get("isExists");
                if (isExists) {
                    insManagerQo = (InsManagerQo) result.get("insManagerQo");
                } else {
                    ResponseData responseData = new ResponseData();
                    responseData.setCode(GenericResponse.CODE_OK);
                    responseData.setList(null);
                    responseData.setMsg("商户订单号不存在");
                    responseData.setData(null);
                    responseData.setTotal(0);

                    return responseData;
                }
            }

            try {
                List<PlicyClassVO> policyAttributes = policyAttributeService.getProInfo("wxb", "2", "0");
                if (policyAttributes != null && policyAttributes.size() > 0) {
                    insManagerQo.setProductType(policyAttributes.stream().map(PlicyClassVO::getCode).collect(Collectors.joining(",")));
                }

            } catch (Exception e) {
                e.printStackTrace();
                ResponseData responseData = new ResponseData();
                responseData.setCode(GenericResponse.CODE_OK);
                responseData.setList(null);
                responseData.setMsg("教育后端获取产品编码失败");
                responseData.setData(null);
                responseData.setTotal(0);

                return responseData;
            }
        }

        log.debug("{}请求投保中心参数 insManagerQo= {}", findCode, JSON.toJSONString(insManagerQo));
        ResponseData rets = null;
        // renewalFlag = true 展业端查询待续保列表
        if (insManagerQo.getRenewalFlag()) {
            log.debug("{}展业端查询待续保列表开始时间{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
            rets = insClient.selectEduPcRenewalList(JSON.toJSONString(insManagerQo));
            log.debug("{}展业端查询待续保列表结束时间{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
            return rets;
        }

        log.debug("{}投保中心请求开始时间{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
        rets = insClient.searchManagerAppList(JSON.toJSONString(insManagerQo));
        log.debug("{}投保中心请求结束时间{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));

        //判断 结果集是不是空的
        if (null == rets || null == rets.getList()) {
            ResponseData responseData = new ResponseData();
            responseData.setCode(GenericResponse.CODE_OK);
            responseData.setList(null);
            responseData.setMsg("投保中心未查询到数据");
            responseData.setData(null);
            responseData.setTotal(0);

            return responseData;
        }
        //投保中心返回的结果集
        List<InsManagerResultVO> list = (List<InsManagerResultVO>) rets.getList();
        list = JSON.parseArray(JSON.toJSONString(list), InsManagerResultVO.class);

        //如果是我学保添加特殊处理逻辑
        if ("02".equals(insManagerQo.getChannelType()) || "02,0001".equals(insManagerQo.getChannelType())) {
            log.debug("{}添加商户订单号请求开始时间{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
            //添加商户订单号
            setTradeNo(list);
            log.debug("{}添加商户订单号请求结束时间{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
        }
        log.debug("{}添加扩展信息请求开始时间{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
        //添加扩展信息
        extendService.setExtends(list, insManagerQo.getChannelType(), isDown, true);
        log.debug("{}添加扩展信息请求结束时间{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));

        rets.setList(list);
        return rets;
    }

    /*
     * 统计投保单人数以及金额
     * @Author xq.wu
     * @Date 13:46 2020/4/16
     * @Param [insManagerQo, findCode]
     * @return com.jt.www.model.remote.ins.EduPolicyStatisticsVo
     **/
    @Override
    public EduPolicyStatisticsVo statisticsAppilications(InsManagerQo insManagerQo, String findCode) throws Exception {
        //获取列表数据
        ResponseData applicationList = findApplicationForm(insManagerQo, findCode, false);
        List<InsManagerResultVO> insManagerResultVOS = (List<InsManagerResultVO>) applicationList.getList();
        insManagerResultVOS = JSON.parseArray(JSON.toJSONString(insManagerResultVOS), InsManagerResultVO.class);
        BigDecimal actualPremSum = new BigDecimal(0); //保费合计
        BigDecimal afterPremSum = new BigDecimal(0); //实付保费合计
        Integer insuredStudentSum = 0; //学生人数合计
        Integer insuredTeacherSum = 0; //教师人数合计
        //远程获取列表总保费和金额
        ResponseData allSerachManagerStatis = insClient.searchManagerStatisticsAppList(JSON.toJSONString(insManagerQo));
        String allActualPremSum = (String) ((LinkedHashMap) allSerachManagerStatis.getData()).get("actualPremSum"); //实付
        String allAfterPremSum = (String) ((LinkedHashMap) allSerachManagerStatis.getData()).get("afterPremSum"); // 投保单保费
        for (int i = 0; i < insManagerResultVOS.size(); i++) {
            actualPremSum = actualPremSum.add((StringUtils.isEmpty(insManagerResultVOS.get(i).getActualPrem()) ? BigDecimal.ZERO : new BigDecimal(insManagerResultVOS.get(i).getActualPrem())));
            afterPremSum = afterPremSum.add((StringUtils.isEmpty(insManagerResultVOS.get(i).getAfterPrem()) ? BigDecimal.ZERO : new BigDecimal(insManagerResultVOS.get(i).getAfterPrem())));
            insuredStudentSum = insuredStudentSum + new Integer((StringUtils.isEmpty(insManagerResultVOS.get(i).getInsuredStudentNum()) ? 0 : new Integer(insManagerResultVOS.get(i).getInsuredStudentNum())));
            insuredTeacherSum = insuredTeacherSum + new Integer((StringUtils.isEmpty(insManagerResultVOS.get(i).getInsuredTeacherNum()) ? 0 : new Integer(insManagerResultVOS.get(i).getInsuredTeacherNum())));
        }
        EduPolicyStatisticsVo eduPolicyStatisticsVo = new EduPolicyStatisticsVo();
        eduPolicyStatisticsVo.setActualPremSum(actualPremSum);
        eduPolicyStatisticsVo.setAfterPremSum(afterPremSum);
        eduPolicyStatisticsVo.setInsuredStudentSum(insuredStudentSum);
        eduPolicyStatisticsVo.setInsuredTeacherSum(insuredTeacherSum);
        eduPolicyStatisticsVo.setAllActualPremSum((StringUtils.isEmpty(allActualPremSum) ? "0" : allActualPremSum));
        eduPolicyStatisticsVo.setAllAfterPremSum((StringUtils.isEmpty(allAfterPremSum) ? "0" : allAfterPremSum));
        return eduPolicyStatisticsVo;
    }

    /*
     *  查询报文重发列表
     * @Author xq.wu
     * @Date 10:52 2019/10/28
     * @Param [issueRetransQo]
     * @return com.github.pagehelper.PageInfo
     **/
    @Override
    public PageInfo findIssueList(IssueRetransQo issueRetransQo) throws Exception {
        log.debug("前端传递参数 ，{}", JSON.toJSONString(issueRetransQo));
        if (issueRetransQo.getPn() == null || issueRetransQo.getPs() == null) {
            throw new ParamException("分页参数不能为空");
        }
        Weekend<IssueListenEntity> weekend = Weekend.of(IssueListenEntity.class);
        WeekendCriteria<IssueListenEntity, Object> criteria = weekend.weekendCriteria();
        if (!StringUtils.isEmpty(issueRetransQo.getAppCode())) {
            criteria.andEqualTo(IssueListenEntity::getApplicationFormCode, issueRetransQo.getAppCode());

        }
        if (!StringUtils.isEmpty(issueRetransQo.getHolderName())) {
            criteria.andEqualTo(IssueListenEntity::getHolderName, issueRetransQo.getHolderName());
        }
        if (!StringUtils.isEmpty(issueRetransQo.getOperator())) {
            criteria.andEqualTo(IssueListenEntity::getOperatorName, issueRetransQo.getOperator());
        }
        if (!StringUtils.isEmpty(issueRetransQo.getInsuredName())) {
            criteria.andEqualTo(IssueListenEntity::getInsuredName, issueRetransQo.getInsuredName());
        }
        if (!StringUtils.isEmpty(issueRetransQo.getProductName())) {
            criteria.andEqualTo(IssueListenEntity::getProductName, issueRetransQo.getProductName());

        }
        if (!StringUtils.isEmpty(issueRetransQo.getSendStartEnd())) {
            criteria.andLessThan(IssueListenEntity::getSendTime, issueRetransQo.getSendStartEnd());
        }
        if (!StringUtils.isEmpty(issueRetransQo.getSendStartFrom())) {
            criteria.andGreaterThan(IssueListenEntity::getSendTime, issueRetransQo.getSendStartFrom());
        }
        weekend.setOrderByClause(ORDER_BY_ID);
        Page page = PageHelper.startPage(issueRetransQo.getPn(), issueRetransQo.getPs());
        List<IssueListenEntity> entities = issueListenerEntityMapper.selectByExample(weekend);
        PageInfo info = new PageInfo(page);
        info.setList(entities);
        return info;

    }

    /**
     * 我学保保单列表设置商户订单号入参
     *
     * @param insManagerQo
     * @return
     */
    private Map<String, Object> setTradeNoParam(InsManagerQo insManagerQo) {

        Map<String, Object> result = new HashMap<>();
        result.put("isExists", true);
        result.put("insManagerQo", insManagerQo);

        PayRecordEntity payRecordEntity = new PayRecordEntity();
        payRecordEntity.setIsDeleted(false);
        payRecordEntity.setTradeno(insManagerQo.getTradeNo());
        List<PayRecordEntity> payRecordEntities = payRecordEntityMapper.select(payRecordEntity);

        if (payRecordEntities != null && payRecordEntities.size() > 0) {
            if (StringUtils.isNotBlank(payRecordEntities.get(0).getOrdersubno())) {
                if (StringUtils.isNotBlank(insManagerQo.getAppCode())
                        && !insManagerQo.getAppCode().equals(payRecordEntities.get(0).getOrdersubno())) {
                    result.put("isExists", false);
                    return result;
                }
            } else {
                if (StringUtils.isNotBlank(insManagerQo.getOrderCode())) {
                    if (!insManagerQo.getOrderCode().equals(payRecordEntities.get(0).getOrderno())) {
                        result.put("isExists", false);
                        return result;
                    }
                } else {
                    insManagerQo.setOrderCode(payRecordEntities.get(0).getOrderno());
                    result.put("isExists", true);
                    result.put("insManagerQo", insManagerQo);
                    return result;
                }
            }
        } else {
            result.put("isExists", false);
            return result;
        }
        return result;
    }

    /**
     * 我学保添加商户订单号
     *
     * @param list 投保中心返回的结果集
     * @user shaoyunan
     */
    private void setTradeNo(List<InsManagerResultVO> list) {
        //通过定单号查询

        //分批特定的投保单数执行添加商户订单号
        for (int i = 0; i < list.size(); i += DEFUALT_QUERY_NUM) {
            //执行特定个数
            List<String> orderCodes = new ArrayList<>(DEFUALT_QUERY_NUM);
            for (int j = i; j < list.size() && j < i + DEFUALT_QUERY_NUM; j++) {
                orderCodes.add(list.get(j).getOrderCode());
            }
            //获得定单号对应的商户订单号集合的map
            Map<String, List<PayRecordEntity>> payRecordMap = getPayRecordMap(orderCodes);
            //为这个批次添加商户订单号
            for (int j = i; j < list.size() && j < i + DEFUALT_QUERY_NUM; j++) {
                //添加商户订单号
                InsManagerResultVO insManagerResultVO = list.get(j);
                List<PayRecordEntity> payRecordList = payRecordMap.get(insManagerResultVO.getOrderCode());
                if (CollectionUtils.isNotEmpty(payRecordList)) {
                    for (PayRecordEntity payRecordEntity : payRecordList) {
                        //如果投保单号相同，或以订单做的支付
                        if (StringUtils.isBlank(payRecordEntity.getOrdersubno()) ||
                                insManagerResultVO.getAppCode().equals(payRecordEntity.getOrdersubno())) {
                            insManagerResultVO.setTradeNo(payRecordEntity.getTradeno());
                        }
                    }
                }
            }
        }
    }

    /**
     * 获得定单号对应的商户订单号集合的map
     *
     * @param orderCodes
     * @user shaoyunan
     */
    private Map<String, List<PayRecordEntity>> getPayRecordMap(List<String> orderCodes) {
        List<PayRecordEntity> payRecordList = payRecordEntityMapper.selectByHandlestatusAndOrderno(orderCodes);
        //listToMap 有可能有一个订单对应多个投保单的情况
        return payRecordList.stream().collect(Collectors.groupingBy(PayRecordEntity::getOrderno));
    }


    /**
     * 设置省,市编码
     *
     * @param dataArea 用户中心返回的省市编码
     */
    private Map setProAndCityCode(String dataArea) {
        //
        StringBuffer buffProvinceCode = new StringBuffer();
        StringBuffer buffCityCode = new StringBuffer();
        if (StringUtils.isNotBlank(dataArea)) {
            String[] dataAreas = dataArea.split(",");
            for (String code : dataAreas) {
                //String subCode = code.substring(code.length()-4, code.length()) ;
                if (code.endsWith("0000")) {//代表是省编码
                    buffProvinceCode.append(code).append(",");
                } else {//市编码
                    buffCityCode.append(code).append(",");
                }
            }
        }
        String provinceCode = "";
        String cityCode = "";
        if (buffProvinceCode.length() > 0) {
            provinceCode = buffProvinceCode.substring(0, buffProvinceCode.length() - 1);
        }
        if (buffCityCode.length() > 0) {
            cityCode = buffCityCode.substring(0, buffCityCode.length() - 1);
        }

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("province", provinceCode);
        map.put("city", cityCode);
        return map;
    }


    @Override
    public List<InsManagerResultVO> downAppList(InsManagerQo insManagerQo, String findCode) throws Exception {

        log.debug("{}导出投保单列表, 查询列表开始:{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
        ResponseData rets = findApplicationFormHasUserInfo(insManagerQo, findCode, true);
        log.debug("{}导出投保单列表, 查询列表结束:{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));

        //判断 结果集是不是空的
        if (null == rets || null == rets.getList()) {
            return Lists.newArrayList();
        }
        //投保中心返回的结果集
        List<InsManagerResultVO> list = (List<InsManagerResultVO>) rets.getList();
        list = JSON.parseArray(JSON.toJSONString(list), InsManagerResultVO.class);

        log.debug("{}导出投保单列表,调用投保中心结束，共{}条", findCode, list.size());
        //如果是山西的模板 添加主险和附加险基础保费金额
        if (ExcelDownFileEnum.EDU_19PR596839.getProductCode().equals(insManagerQo.getProductCode())) {
            log.debug("{}导出山西投保单列表, 添加险种信息开始:{}", DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
            setProgrameBasicPrem(list);
            log.debug("{}导出山西投保单列表, 添加险种信息开始:{}", DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
        }

        //如果是山东的模板,增加各家保险公司跟单号

        if (SD_LIST.contains(insManagerQo.getProductCode())) {
            log.debug("{}导出山东投保单列表, 添加跟单号信息开始:{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
            setBackApplicationFormCode(list, findCode);
            log.debug("{}导出山东投保单列表, 添加跟单号信息结束:{}", findCode, DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));
        }

        return list;
    }


//    /**
//     *  @Description  山东险种远程调用投保中心
//     *                增加跟单号信息
//     * @Author xq.wu
//     * @Date 10:33 2019/10/30
//     * @Param [list]
//     * @return void
//     **/
//    private void setBackApplicationFormCode(List<InsManagerResultVO> list, String findCode) throws Exception {
//        for (int i = 0; i < list.size(); i += DEFUALT_QUERY_NUM) {
//            List<Long> appIds = new ArrayList<>(DEFUALT_QUERY_NUM);
//            for (int j = i; j < list.size() && j < i + DEFUALT_QUERY_NUM; j++) {
//                //投保单ID
//                appIds.add(list.get(j).getId());
//            }
//            //查询条件
//            EduExtendQo eduExtendQo = new EduExtendQo();
//            //添加准备查询的id
//            eduExtendQo.setAppIds(appIds);
//            ResponseEntity<GenericListResponse<InsuranceCompanyVO>> rets = insClient.getBatchBackPolicyNo(JSON.toJSONString(eduExtendQo));
//            //投保中心返回的结果集
//            List<InsuranceCompanyVO> insuranceCompanyVOS;
//            //判断 结果集是不是空的
//            if (null == rets || null == rets.getBody() || CollectionUtils.isEmpty(insuranceCompanyVOS = rets.getBody().getList())) {
//                continue;
//            }
//            String backPolicyNo = "";
//            String issueCode = "";
//            for (int j = i; j < list.size() && j < i + DEFUALT_QUERY_NUM; j++) {
//                for (InsuranceCompanyVO insuranceCompanyVO : insuranceCompanyVOS) {
//                    if (list.get(j).getAppCode().equals(insuranceCompanyVO.getBackApplicationFormCode())) {
//                        issueCode = insuranceCompanyVO.getCode().substring(0, 10);
//                        backPolicyNo = insuranceCompanyVO.getBackPolicyNo();
//                    }
//                    if (issueCode.equals(IssueCodeEnum.SD_YG.getCode())) {
//                        list.get(j).setYgInsuranceNo(backPolicyNo);
//                    }
//                    if (issueCode.equals(IssueCodeEnum.SD_YA.getCode())) {
//                        list.get(j).setYaInsuranceNo(backPolicyNo);
//                    }
//                    if (issueCode.equals(IssueCodeEnum.SD_PA.getCode())) {
//                        list.get(j).setGsInsuranceNo(backPolicyNo);
//                    }
//                    if (issueCode.equals(IssueCodeEnum.SD_RB.getCode())) {
//                        list.get(j).setRbInsuranceNo(backPolicyNo);
//                    }
//                    if (issueCode.equals(IssueCodeEnum.SD_GS.getCode())) {
//                        list.get(j).setGsInsuranceNo(backPolicyNo);
//                    }
//                    if (issueCode.equals(IssueCodeEnum.SD_TB.getCode())) {
//                        list.get(j).setTbInsuranceNo(backPolicyNo);
//                    }
//                }
//            }
//        }
//    }


    private void setBackApplicationFormCode(List<InsManagerResultVO> list, String findCode) throws Exception {

        Lists.partition(list, DEFUALT_QUERY_NUM).stream().parallel().forEach(lists -> {
            List<Long> appIds = Lists.newArrayList(Iterables.transform(lists, input -> input.getId()));
            //查询条件
            EduExtendQo eduExtendQo = new EduExtendQo();
            //添加准备查询的id
            eduExtendQo.setAppIds(appIds);
            ResponseEntity<GenericListResponse<InsuranceCompanyVO>> rets = null;
            try {
                rets = insClient.getBatchBackPolicyNo(JSON.toJSONString(eduExtendQo));
            } catch (Exception e) {
                log.error("{} 山东跟单号查询异常，请求参数{}", findCode, JSON.toJSONString(eduExtendQo));
            }
            //投保中心返回的结果集
            List<InsuranceCompanyVO> insuranceCompanyVOS;
            //判断 结果集是不是空的
            if (null == rets || null == rets.getBody() || CollectionUtils.isEmpty(insuranceCompanyVOS = rets.getBody().getList())) {
                return;
            }
            lists.stream().forEach(insManagerResultVO ->
                    insuranceCompanyVOS.stream().forEach(insuranceCompanyVO -> {
                        if (insManagerResultVO.getAppCode().equals(insuranceCompanyVO.getBackApplicationFormCode())) {
                            String issueCode = insuranceCompanyVO.getCode().substring(0, 10);
                            String backPolicyNo = insuranceCompanyVO.getBackPolicyNo();
                            IssueCodeEnum issueCodeEnum = IssueCodeEnum.getIssueCodeEnumByCode(issueCode);
                            if (issueCodeEnum != null) {
                                switch (issueCodeEnum) {
                                    case SD_YG:
                                        insManagerResultVO.setYgInsuranceNo(backPolicyNo);
                                        break;
                                    case SD_YA:
                                        insManagerResultVO.setYaInsuranceNo(backPolicyNo);
                                        break;
                                    case SD_PA:
                                        insManagerResultVO.setPaInsuranceNo(backPolicyNo);
                                        break;
                                    case SD_RB:
                                        insManagerResultVO.setRbInsuranceNo(backPolicyNo);
                                        break;
                                    case SD_GS:
                                        insManagerResultVO.setGsInsuranceNo(backPolicyNo);
                                        break;
                                    case SD_TB:
                                        insManagerResultVO.setTbInsuranceNo(backPolicyNo);
                                        break;
                                    case SD_ZHLH:
                                        insManagerResultVO.setZhlhInsuranceNo(backPolicyNo);
                                        break;
                                    case SD_DD:
                                        insManagerResultVO.setDdInsuranceNo(backPolicyNo);
                                        break;
                                    default:
                                }
                            }
                        }
                    })
            );
        });

    }

    /**
     * 为投保单列表添加主险附加险的保单基本信息
     *
     * @param list
     */
    private void setProgrameBasicPrem(List<InsManagerResultVO> list) throws Exception {
        //分批特定的投保单数执行添加扩展字段
        for (int i = 0; i < list.size(); i += DEFUALT_QUERY_NUM) {
            //指定特定个数的投保单id
            List<Long> appIds = new ArrayList<>(DEFUALT_QUERY_NUM);
            for (int j = i; j < list.size() && j < i + DEFUALT_QUERY_NUM; j++) {
                //投保单ID
                appIds.add(list.get(j).getId());
            }
            //查询条件
            EduExtendQo eduExtendQo = new EduExtendQo();
            //添加准备查询的id
            eduExtendQo.setAppIds(appIds);
            ResponseEntity<GenericListResponse<EduExtendVO>> rets = insClient.selectPrograme(JSON.toJSONString(eduExtendQo));
            //投保中心返回的结果集
            List<EduExtendVO> eduExtendVOS;
            //判断 结果集是不是空的
            if (null == rets || null == rets.getBody() || CollectionUtils.isEmpty(eduExtendVOS = rets.getBody().getList())) {
                continue;
            }

            for (int j = i; j < list.size() && j < i + DEFUALT_QUERY_NUM; j++) {
                //给返回结果赋值
                for (EduExtendVO eduExtendVO : eduExtendVOS) {
                    //通过投保单id找到对应的投保单信息
                    if (list.get(j).getId().equals(eduExtendVO.getAppId())) {
                        //通过查询出来的产品编码得到
                        String prem = ProgrameBasicPremEnum.getPremByProgrameCode(eduExtendVO.getFieldValues());
                        //主险
                        if ("M".equals(eduExtendVO.getFieldCode())) {
                            list.get(j).setMainBasicPrem(prem);
                        } else {
                            //附加险
                            list.get(j).setAddBasicPrem(prem);
                        }
                    }
                }
            }
        }
    }

    @Override
    public void downAppFormToPDF(String applicationFormCode) throws Exception {

        String findCode = "EDU_" + System.currentTimeMillis();

        log.debug(findCode + "下载投保单生成PDF 前端传递参数 ，投保单号：{}", applicationFormCode);

        String source = "00";
        String html = insClient.generateHtml(applicationFormCode, source);

        log.debug(findCode + "下载投保单生成PDF 调用投保中心获取html接口 ，html ：{}", html);

        String path = "投保单" + applicationFormCode + ".pdf";
        FileOutputStream fileOutputStream = new FileOutputStream(path);
        fileOutputStream.write(Html2PdfUtil.convert(html));
        fileOutputStream.close();
        log.debug(findCode + "下载投保单生成PDF完成");
    }


    private String getHtmlByPageName(String pageName) throws IOException {
        String path = "/templates/" + pageName + ".html";
        // 返回读取指定资源的输入流
        InputStream is = this.getClass().getResourceAsStream(path);
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String s = "";
        StringBuffer sb = new StringBuffer();
        while ((s = br.readLine()) != null) {
            sb.append(s).append("\n");
        }
        return sb.toString();

    }

    private void getAccountList(WebContext ctx, AppDetailProVo appDetailProVo) {
        //调用用户中心 根据省市区查询机构账户信息
        ResponseEntity<GenericDataResponse<JtBranchAccountVo>> jtBranchAccount = null;
        try {
            jtBranchAccount = previewService.branchAccount(appDetailProVo.getInsuredList().get(0).getCorporation().getCountyCode(), "edu", appDetailProVo.getProductCode());
        } catch (Exception e) {
            log.error("根据省市区查询机构账户信息失败===》投保单号：" + appDetailProVo.getApplicationFormCode(), e);
            e.printStackTrace();
        }
        GenericDataResponse<JtBranchAccountVo> body = jtBranchAccount.getBody();
        if (null != body && null != body.getData()) {
            JtBranchAccountVo data = body.getData();
            List<AccountVo> accountVoList = data.getAccountVoList();
            for (AccountVo account : accountVoList) {
                //户名
                String bankName = account.getBankName();
                //开户行
                String bankAccountNameaccount = account.getBankAccountName();
                //账号
                String bankAccountNo = account.getBankAccountNo();
                ctx.setVariable("bankName", bankName);
                ctx.setVariable("bankAccountNameaccount", bankAccountNameaccount);
                ctx.setVariable("bankAccountNo", bankAccountNo);
            }
        }
    }

    /**
     * 投保单pdf下载
     *
     * @param param
     * @param model
     * @param request
     * @param response
     * @throws Exception
     */
    @Override
    public void downAppFormPdf(AppDetailProParam param, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {

        String findCode = "EDU_" + System.currentTimeMillis();
        WebContext ctx = new WebContext(request, response, request.getServletContext(), request.getLocale());
        log.debug(findCode + "下载投保单生成PDF 前端传递参数 ，投保单号：{}", param);
        AppDetailProVo appDetailProVo = previewService.searchAppDetailPro(param);
        //计算保险期间 月数
        if (StringUtils.isNotBlank(appDetailProVo.getStartDate()) && org.apache.commons.lang.StringUtils.isNotBlank(appDetailProVo.getEndDate())) {
            String startDate = appDetailProVo.getStartDate();
            String endDate = appDetailProVo.getEndDate();
            int months = DateUtils.getMonthDiff(
                    DateUtils.str2Date(startDate, DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS),
                    DateUtils.str2Date(endDate, DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS));

            ctx.setVariable("months", months);
        }
        //获取基本信息
        getInsuredFor(ctx, appDetailProVo);
        //获取险种编码
        getRiskList(ctx, appDetailProVo);
        //获取投保人数
        getStudentAmount(ctx, appDetailProVo);
        //获取出单信息
        getInsurance(ctx, appDetailProVo);
        //获取开户行
        getAccountList(ctx, appDetailProVo);
        //获取投保联系人信息
        getLinkManInfo(ctx, appDetailProVo);
        //获取标的列表信息
        getExtendsList(ctx, appDetailProVo);

        //获取到投保中心金额进行大小写转换
        String premiumStr = MoneyUtil.CNValueOf(appDetailProVo.getAfterPrem());
        ctx.setVariable("premiumStr", premiumStr);
        ctx.setVariable("ins", appDetailProVo);

        //若为实责，企业、学校使用投保单模板不同
        String code = "";
        if (PolicyTypeEnum.TRAINEE_ENT.getProductCode().equals(appDetailProVo.getProductCode())) {
            if (appDetailProVo.getInsuredList() != null
                    && appDetailProVo.getInsuredList().size() > 0
                    && appDetailProVo.getInsuredList().get(0).getCorporation() != null
                    && appDetailProVo.getInsuredList().get(0).getCorporation().getExtendList() != null
                    && appDetailProVo.getInsuredList().get(0).getCorporation().getExtendList().size() > 0) {
                for (ExtendForProVO extendForProVO : appDetailProVo.getInsuredList().get(0).getCorporation().getExtendList()) {
                    String key = extendForProVO.getKey();
                    String value = extendForProVO.getValue();
                    if (key.equals("S_I_000123")) {
                        code = CORPORATION_ENT.equals(value) ? "0" : "1";
                        break;
                    }
                }
            }
        }

        String policyModel = PolicyTypeEnum.getHtmlTemplateByProductCode(appDetailProVo.getProductCode(), code).getHtmlTemplate();
        String html = getHtmlByPageName(policyModel);
        String htmlcontext = templateEngine.process(policyModel, ctx);
        log.debug(findCode + "下载投保单生成PDF，html ：{}", html);

        String path = "投保单" + param.getAppCode() + ".pdf";
        response.addHeader("Content-Disposition",
                "attachment;fileName=" + URLEncoder.encode(path, "UTF-8"));
        response.setHeader("Content-Type", "application/pdf");
        ServletOutputStream outputStream = response.getOutputStream();

        outputStream.write(Html2PdfUtil.convert(htmlcontext));
        outputStream.close();
        log.debug(findCode + "下载投保单生成PDF完成");
    }

    private void getExtendsList(WebContext ctx, AppDetailProVo appDetailProVo) {
        ResponseEntity<GenericListResponse<DetailVo>> appDetailPro = previewService.insuranceObjects(appDetailProVo.getApplicationFormCode());
        if (null != appDetailPro && null != appDetailPro.getBody() && appDetailPro.getBody().getTotal() > 0) {
            List<DetailVo> detailVos = appDetailPro.getBody().getList();
            ctx.setVariable("extendsDetailVos", detailVos);

            //实责（学校）、校责（学校）计算各人数合计
            if (appDetailProVo.getProductCode().equals(PolicyTypeEnum.STUDENT_SCH.getProductCode())
                    || appDetailProVo.getProductCode().equals(PolicyTypeEnum.TRAINEE_SCH.getProductCode())
                    || appDetailProVo.getProductCode().equals(PolicyTypeEnum.TRAINEE_ENT.getProductCode())) {

                Integer zcxss = 0;//在册学生数 S_O_000020
                Integer tbxss = 0;//投保学生数 S_O_000021 实责
                Integer xz_tbxss = 0;//投保学生数 S_O_000027 校责
                Integer pqjss = 0;//派遣教师数 S_O_000023
                Integer bbxrs = 0;//附加被保险人数 S_O_000024
                Integer wgsrs = 0;//附加实习无过失人数 S_O_000025
                Integer xfwgs = 0;//附加校方无过失 S_O_000030
                Integer xwwgs = 0;//附加校外无过失 S_O_000064
                Integer crb = 0;//附加传染病 S_O_000065

                Integer S_O_000024 = 0;//每个年级 附加被保险人数 = 附加被保险人数S_O_000024 + 附加实习和附加被保险同时投保人数S_O_000063
                Integer S_O_000025 = 0;//每个年级 附加实习无过失人数 = 附加实习无过失人数S_O_000025 + 附加实习和附加被保险同时投保人数S_O_000063
                for (DetailVo vo : detailVos) {
                    S_O_000024 = 0;
                    S_O_000025 = 0;
                    for (Map<String, Object> map : vo.getExtendsList()) {
                        if (map.get("fieldValues") != null
                                && !"".equals(map.get("fieldValues"))
                                && !"invalidation".equals(map.get("fieldValues"))) {
                            switch (map.get("fieldCode").toString()) {
                                case "S_O_000020":
                                    zcxss += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000021":
                                    tbxss += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000023":
                                    pqjss += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000024":
                                    bbxrs += Integer.valueOf(map.get("fieldValues").toString());
                                    S_O_000024 += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000025":
                                    wgsrs += Integer.valueOf(map.get("fieldValues").toString());
                                    S_O_000025 += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000027":
                                    xz_tbxss += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000030":
                                    xfwgs += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000063":
                                    bbxrs += Integer.valueOf(map.get("fieldValues").toString());
                                    wgsrs += Integer.valueOf(map.get("fieldValues").toString());
                                    S_O_000024 += Integer.valueOf(map.get("fieldValues").toString());
                                    S_O_000025 += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000064":
                                    xwwgs += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                                case "S_O_000065":
                                    crb += Integer.valueOf(map.get("fieldValues").toString());
                                    break;
                            }
                        }
                    }
                    Map<String, Object> bbxrsMap = new HashMap<>();
                    bbxrsMap.put("fieldCode", "bbxrs_num");
                    bbxrsMap.put("fieldValues", S_O_000024);
                    vo.getExtendsList().add(bbxrsMap);
                    Map<String, Object> wgsrsMap = new HashMap<>();
                    wgsrsMap.put("fieldCode", "wgsrs_num");
                    wgsrsMap.put("fieldValues", S_O_000025);
                    vo.getExtendsList().add(wgsrsMap);
                }
                ctx.setVariable("zcxss", zcxss);
                ctx.setVariable("tbxss", tbxss);
                ctx.setVariable("xz_tbxss", xz_tbxss);
                ctx.setVariable("pqjss", pqjss);
                ctx.setVariable("bbxrs", bbxrs);
                ctx.setVariable("wgsrs", wgsrs);
                ctx.setVariable("xfwgs", xfwgs);
                ctx.setVariable("xwwgs", xwwgs);
                ctx.setVariable("crb", crb);
                ctx.setVariable("extendsDetailVos", detailVos);
            }

            List<Map<String, Object>> extendsList = detailVos.get(0).getExtendsList();
            ctx.setVariable("extendsList", extendsList);
        }
    }

    private void getLinkManInfo(WebContext ctx, AppDetailProVo appDetailProVo) {
        try {
            EduOrgsVO user = new EduOrgsVO();

            if (StringUtils.isBlank(appDetailProVo.getHolder().getHolderCode())) {
                throw new BizException("投保人userCode为空");
            }

            ResponseEntity<GenericDataResponse<EduAuthenInfoDetails>> result = userClient.queryAuthentEduInfo(appDetailProVo.getHolder().getHolderCode());
            if (result == null) {
                throw new BizException("用户信息调用失败");
            }
            EduAuthenInfoDetails eduAuthenInfoDetails = result.getBody().getData();
            if (eduAuthenInfoDetails == null) {
                throw new BizException("找不到该用户");
            }
            List<OrgElementVO> custOrganizationElementList = eduAuthenInfoDetails.getCustOrganizationElementList();
            for (OrgElementVO orgElementVO : custOrganizationElementList) {
                if (orgElementVO.getElementCode().equals("linkManEmail")) {
                    user.setLinkManEmail(orgElementVO.getElementValues());
                } else if (orgElementVO.getElementCode().equals("linkManPhone")) {
                    user.setLinkManPhone(orgElementVO.getElementValues());
                } else if (orgElementVO.getElementCode().equals("linkManName")) {
                    user.setLinkManName(orgElementVO.getElementValues());
                }
            }
            ctx.setVariable("linkMan", user);
        } catch (Exception e) {
            log.error("下载投保单pdf异常{}", e);
        }
    }

    private void getInsurance(WebContext ctx, AppDetailProVo appDetailProVo) {
        //获取出单公司信息
        List<com.jt.www.model.vo.sdCheck.InsuranceCompanyVO> insuranceCompanyVOS = appDetailProVo.getInsuranceCompanyVOS();
        if (insuranceCompanyVOS != null && insuranceCompanyVOS.size() > 0) {

            for (com.jt.www.model.vo.sdCheck.InsuranceCompanyVO insureTrackVO : insuranceCompanyVOS) {
                if (StringUtils.isNotBlank(insureTrackVO.getRole2()) && "01".equals(insureTrackVO.getRole2())) {
                    ctx.setVariable("issuingCompany", insureTrackVO.getName());
                }
            }
            //排除出单公司
            insuranceCompanyVOS = insuranceCompanyVOS.stream().filter(obj -> "01".equals(obj.getRole1()) || "02".equals(obj.getRole1()) || "03".equals(obj.getRole1())).collect(Collectors.toList());
        }
        ctx.setVariable("companys", insuranceCompanyVOS);
        ctx.setVariable("companysSize", insuranceCompanyVOS != null ? insuranceCompanyVOS.size() : 0);
    }

    private void getStudentAmount(WebContext ctx, AppDetailProVo appDetailProVo) {
        //获取投保人数
        List<PremiunFactorVo> premiunFactorVos = appDetailProVo.getPremiunFactorVos();
        if (premiunFactorVos != null && premiunFactorVos.size() > 0) {

            for (PremiunFactorVo premiunFactorVo : premiunFactorVos) {
                if (org.apache.commons.lang.StringUtils.isNotBlank(premiunFactorVo.getFieldCode())) {
                    if (premiunFactorVo.getFieldCode().equals("19YZ159166")) {
                        String amountStudent = premiunFactorVo.getFieldValue();
                        ctx.setVariable("amountStudent", amountStudent);
                    }
                    String filedValue = premiunFactorVo.getFieldValue();
                    ctx.setVariable("fieldCode" + premiunFactorVo.getFieldCode(), filedValue);
                }

            }
        }
    }

    private void getRiskList(WebContext ctx, AppDetailProVo appDetailProVo) {
        //获取方案编码
        List<Map<String, Object>> riskList = appDetailProVo.getRiskList();
        for (int i = 0; i < riskList.size(); i++) {
            Object value = riskList.get(i).get("programCode");
            ctx.setVariable("programCode" + i, value);
        }
        ctx.setVariable("riskList", riskList);
    }

    //获取基本信息
    private void getInsuredFor(WebContext ctx, AppDetailProVo appDetailProVo) {
        //获取基础信息扩展字段
        List<InsuredForProVO> insuredList = appDetailProVo.getInsuredList();
        if (insuredList != null && insuredList.size() > 0) {
            for (InsuredForProVO insuredForProVO : insuredList) {
                CorporationForProVO corporationForProVO = insuredForProVO.getCorporation();
                List<ExtendForProVO> extendForProVOS = corporationForProVO.getExtendList();
                if (corporationForProVO != null && extendForProVOS.size() > 0) {
                    for (ExtendForProVO extendForProVO : extendForProVOS) {
                        //学校性质 学校类型 学制
                        String key = extendForProVO.getKey();
                        String value = extendForProVO.getValue();
                        if (key.equals("S_I_000089")) {
                            //映射学校类型名称
                            String schoolTypeName = SchoolTypeEnum.getMsgByCode(value);
                            ctx.setVariable(key, schoolTypeName);
                        } else {
                            ctx.setVariable(key, value);
                        }

                    }
                }

                List<CommonInsuranceObjectVo> insuranceObjectVos = insuredForProVO.getInsuranceObjectVos();
                if (insuranceObjectVos != null && insuranceObjectVos.size() > 0) {
                    for (CommonInsuranceObjectVo commonInsuranceObjectVo : insuranceObjectVos) {
                        ctx.setVariable("carNumber", commonInsuranceObjectVo.getObjectId());
                        if (commonInsuranceObjectVo.getCommonExtendVoList().size() > 0) {
                            for (CommonExtendVo commonExtendVo : commonInsuranceObjectVo.getCommonExtendVoList()) {
                                String key = commonExtendVo.getFieldCode();
                                String value = commonExtendVo.getFieldValues();
                                ctx.setVariable(key, value);
                            }
                        }
                    }
                }
            }
        }
    }


    /**
     * 获取失败的跟单公司
     *
     * @param param
     * @return
     * @throws Exception
     */
    public ResponseData getBackPolicyNoError(AppDetailProParam param) throws Exception {
        if (StringUtils.isEmpty(param.getAppCode())) {
            throw new Exception("投保单号不能为空");
        }
        AppDetailProVo detailVos = null;
        try {
            ResponseEntity<GenericDataResponse<AppDetailProVo>> appDetailProVo = insClient.searchAppDetailPro(param);
            detailVos = appDetailProVo.getBody().getData();
        } catch (Exception e) {
            log.info("查询投保单信息失败{}", param.getAppCode());
        }
        List<com.jt.www.model.vo.sdCheck.InsuranceCompanyVO> errorBackPolicyList = new ArrayList<>();
        //查询是否出单
        if (AppStatusEnum.AS_10.getCode().equals(detailVos.getApplicationStatus()) || AppStatusEnum.AS_21.getCode().equals(detailVos.getApplicationStatus())
                || AppStatusEnum.AS_02.getCode().equals(detailVos.getApplicationStatus()) ||
                AppStatusEnum.AS_03.getCode().equals(detailVos.getApplicationStatus())) {
            List<com.jt.www.model.vo.sdCheck.InsuranceCompanyVO> backPolicyList = detailVos.getInsuranceCompanyVOS();

            for (com.jt.www.model.vo.sdCheck.InsuranceCompanyVO backPolicy : backPolicyList) {
                if (StringUtils.isEmpty(backPolicy.getBackPolicyNo())) {
                    log.info("投保单号{} 跟单待出单保险公司为 {} ", param.getAppCode(), backPolicy.getName());
                    errorBackPolicyList.add(backPolicy);
                }
            }
        }
        ResponseData responseData = new ResponseData();
        responseData.setTotal(errorBackPolicyList.size());
        responseData.setList(errorBackPolicyList);
        return responseData;
    }

    /**
     * 在线查询 （菜单）
     *
     * @param eduPolicyBean
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(readOnly = true)
    public MyPageInfo<EduPolicyVO> onlineQuery(EduPolicyBean eduPolicyBean) throws Exception {
        if (eduPolicyBean == null) {
            throw new Exception("查询条件不能为空");
        }
        String queryType = eduPolicyBean.getQueryType();
        if (StringUtils.isEmpty(queryType)) {
            throw new Exception("查询方式不能为空");
        }

        //默认查询保险止期在两年内的
        LocalDate today = LocalDate.now();
        LocalDate previousYear = today.minus(2, ChronoUnit.YEARS).plus(1, ChronoUnit.DAYS);

        eduPolicyBean.setEndDateFrom(previousYear + " 00:00:00");

        GenericListResponse<EduPolicyVO> result = null;
        String serverName = "";
        switch (queryType) {
            case "1":
                String name = eduPolicyBean.getName();
                String idNum = eduPolicyBean.getIdNum();
                if (StringUtils.isEmpty(name) || StringUtils.isEmpty(idNum)) {
                    throw new Exception("姓名和身份证号码不能为空");
                }
                List<String> appCodeList = endorseMapper.selectByNameAndCertificateTypeAndCardNo(name.trim(), idNum.trim());

                if (appCodeList != null && !appCodeList.isEmpty()) {
                    String appCodes = StringUtils.join(appCodeList, ",");
                    eduPolicyBean.setAppCodes(appCodes);
                    result = insClient.onlineQuery(eduPolicyBean);
                }
                serverName = "投保中心";
                break;
            case "3"://批单号
                if (StringUtils.isEmpty(eduPolicyBean.getQueryConditions()) || StringUtils.isEmpty(eduPolicyBean.getQueryConditions())) {
                    throw new Exception("批单号不能为空");
                }
                eduPolicyBean.setChannelCode("edu");
                eduPolicyBean.setKey("edu_key");
                result = polClient.queryEduEndorsementsInfoList(eduPolicyBean);
                serverName = "保单中心";
                break;
            case "2"://保单号
                if (StringUtils.isEmpty(eduPolicyBean.getPolicyNo()) || StringUtils.isEmpty(eduPolicyBean.getPolicyNo())) {
                    throw new Exception("保单号不能为空");
                }
                result = insClient.onlineQuery(eduPolicyBean);
                serverName = "投保中心";
                break;
            case "4"://学校名称
                if (StringUtils.isEmpty(eduPolicyBean.getSchoolName()) || StringUtils.isEmpty(eduPolicyBean.getSchoolName())) {
                    throw new Exception("学校名称不能为空");
                }
                result = insClient.onlineQuery(eduPolicyBean);
                serverName = "投保中心";
                break;
            default:
                throw new Exception("查询方式错误");
        }
        MyPageInfo<EduPolicyVO> pageInfo = new MyPageInfo<>();
        if (result != null && StringUtils.equals(result.getCode(), "0000")) {
            /*if (StringUtils.equals(queryType, "1") && result.getTotal() > 0) {
                List<EduPolicyVO> list = result.getList();
                String idNum = eduPolicyBean.getIdNum().trim().replaceAll("(\\d{3})\\d{12}(\\d{3})", "$1************$2");
                String name = eduPolicyBean.getName().trim();
                for (EduPolicyVO eduPolicyVO : list) {
                    eduPolicyVO.setIdNum(idNum);
                    eduPolicyVO.setName(name);
                }
            }*/
            if (result.getTotal() > 0) {
                List<EduPolicyVO> list = result.getList();
                for (EduPolicyVO eduPolicyVO : list) {
                    if (StringUtils.isNotBlank(eduPolicyVO.getInsuranceNo())) {
                        eduPolicyVO.setInsuranceNo(MyStringUtils.hiddenCharacters(eduPolicyVO.getInsuranceNo().trim()));
                    }
                    if (StringUtils.isNotBlank(eduPolicyVO.getEndorsementsNo())) {
                        eduPolicyVO.setEndorsementsNo(MyStringUtils.hiddenCharacters(eduPolicyVO.getEndorsementsNo()));
                    }
                }
            }
            pageInfo.setCurrentPage(eduPolicyBean.getPageNum());
            pageInfo.setList(result.getList());
            pageInfo.setPageSize(eduPolicyBean.getPageSize());
            pageInfo.setTotal(result.getTotal());
        } else {
            if (result != null) {
                log.error(serverName + "----->" + result.getMsg());
                throw new Exception(serverName + "服务器出现了一些问题");
            }
            pageInfo.setCurrentPage(eduPolicyBean.getPageNum());
            pageInfo.setList(null);
            pageInfo.setPageSize(eduPolicyBean.getPageSize());
            pageInfo.setTotal(0L);
        }
        return pageInfo;
    }

    /**
     * 查询投保单列表(案件关联保单时使用)
     *
     * @param appForCaseQo
     * @return
     * @throws Exception
     */
    @Override
    public MyPageInfo<AppForCaseVO> appilicationsForCase(AppForCaseQo appForCaseQo) throws Exception {
        String findCode = "appilicationsForCase_" + System.currentTimeMillis();

        if (appForCaseQo == null) {
            throw new Exception("查询条件不能为空");
        }

        MyPageInfo<AppForCaseVO> pageInfo = new MyPageInfo<>();
        log.info("{} 查询投保单列表(案件关联保单时使用) 前端传递参数 ，{}", findCode, JSON.toJSONString(appForCaseQo));

        if (StringUtils.isNotEmpty(appForCaseQo.getStudentTeacherName()) || StringUtils.isNotEmpty(appForCaseQo.getStudentTeacherCardNo())) {

            List<String> appCodeList = endorseMapper.selectEndorseByNameAndCardNo(appForCaseQo.getStudentTeacherName(), appForCaseQo.getStudentTeacherCardNo());

            if (appCodeList.size() <= 0) {

                log.info("{} 查询投保单列表(案件关联保单时使用) 根据学生名称或证件号查询清单人员 未查询到该清单人员", findCode);

                pageInfo.setCurrentPage(appForCaseQo.getPn());
                pageInfo.setList(null);
                pageInfo.setPageSize(appForCaseQo.getPs());
                pageInfo.setTotal(0L);
                return pageInfo;
            }

            log.info("{} 查询投保单列表(案件关联保单时使用) 根据学生名称或证件号查询清单人员 查询到的投保单号->{}", findCode, JsonUtil.object2Json(appCodeList));

            appForCaseQo.setAppCodes(appCodeList);
        }

        if (appForCaseQo.getDiffName() != null) {
            String diffName = appForCaseQo.getDiffName().trim();
            if (StringUtils.isNotBlank(diffName)) {
                List<String> appCodeList = endorseMapper.selectEndorseByNameOrCardNo(diffName);
                if (appCodeList.size() <= 0) {
                    //返回一个空的集合
                    appForCaseQo.setAppCodes(null);
                } else {
                    appForCaseQo.setAppCodes(appCodeList);
                }
            }

            log.info("{} 查询投保单列表(案件关联保单时使用) 根据diffName查询清单人员 查询到的投保单号->{}", findCode, JsonUtil.object2Json(appForCaseQo.getAppCodes()));

        }


        GenericListResponse<AppForCaseVO> result = insClient.appilicationsForCase(appForCaseQo);

        if (result != null && StringUtils.equals(result.getCode(), "0000")) {
            if (result.getTotal() > 0) {

                log.info("{} 查询投保单列表(案件关联保单时使用) 投保中心查询到符合条件保单信息 size->{}", findCode, result.getTotal());

                for (AppForCaseVO v : result.getList()) {
                    //拼装险种信息 险种分为两大类 ：zrx_1-责任险;ywx_1-意外险;
                    if (StringUtils.isNotBlank(v.getProductCode())) {
                        Weekend<RiskInfoEntity> weekend = new Weekend<>(RiskInfoEntity.class);
                        WeekendCriteria<RiskInfoEntity, Object> criteria = weekend.weekendCriteria();

                        criteria.andEqualTo(IS_DELETED, false);
                        criteria.andEqualTo(PRODUCT_CODE, v.getProductCode());

                        List<RiskInfoEntity> riskEntities = riskInfoMapper.selectByExample(weekend);
                        if (!CommonUtils.isEmpty(riskEntities)) {
                            v.setCategoryCode(CategoryEnum.getCaseCode(riskEntities.get(0).getCategoryCode()));
                        }
                    }
                }

                pageInfo.setCurrentPage(appForCaseQo.getPn());
                pageInfo.setList(result.getList());
                pageInfo.setPageSize(appForCaseQo.getPs());
                pageInfo.setTotal(result.getTotal());

                return pageInfo;
            } else {
                log.info("{} 查询投保单列表(案件关联保单时使用) 投保中心未查询到符合条件保单信息 开始查询ebao保单", findCode);
                // 当大平台查询不到保单时，如果保单号不为空，则查询ebao保单

                String policyNo = "";
                if (StringUtils.isNotBlank(appForCaseQo.getDiffName())) {
                    policyNo = appForCaseQo.getDiffName().trim();
                }
                if (StringUtils.isNotBlank(appForCaseQo.getPolicyNo())) {
                    policyNo = appForCaseQo.getPolicyNo().trim();
                }
                if (StringUtils.isNotBlank(policyNo)) {
                    EbaoPolicyQO ebaoPolicyQO = new EbaoPolicyQO();
                    ebaoPolicyQO.setPn(appForCaseQo.getPn());
                    ebaoPolicyQO.setPs(appForCaseQo.getPs());
                    ebaoPolicyQO.setPolicyNo(policyNo);
                    ebaoPolicyQO.setBusType1Code(BUS_TYPE_1_CODE);
                    ebaoPolicyQO.setBusType2Code(BUS_TYPE_2_CODE);

                    log.info("{} 查询投保单列表(案件关联保单时使用) 查询ebao保单 入参->{}", findCode, JsonUtil.object2Json(ebaoPolicyQO));

                    ResponseEntity<GenericListResponse<EbaoPolicyVO>> responseEntity = caseInfoService.ebaoPolicyList(findCode, ebaoPolicyQO);

                    log.info("{} 查询投保单列表(案件关联保单时使用) 查询ebao保单 出参->{}", findCode, JsonUtil.object2Json(responseEntity));

                    if (responseEntity.getBody() != null && responseEntity.getBody().getTotal() > 0) {

                        List<AppForCaseVO> list = new ArrayList<>();

                        responseEntity.getBody().getList().forEach(e -> {
                            AppForCaseVO v = new AppForCaseVO();
                            v.setPolStartDate(DateUtils.str2Date(e.getPolicyStartDate() + " 00:00:00", DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS));
                            v.setPolEndDate(DateUtils.str2Date(e.getPolicyEndDate() + " 23:59:59", DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS));
                            v.setProductName(e.getRiskName());
                            v.setInsuredName(e.getCustomerName());
                            v.setPolicyNo(e.getPolicyNo());
                            v.setHolderName(e.getApplicant());
                            v.setPrem(String.valueOf(e.getPrem().setScale(2, BigDecimal.ROUND_HALF_UP)));
                            v.setActualPrem(String.valueOf(e.getPrem().setScale(2, BigDecimal.ROUND_HALF_UP)));
                            v.setAfterPrem(String.valueOf(e.getPrem().setScale(2, BigDecimal.ROUND_HALF_UP)));

                            list.add(v);
                        });

                        pageInfo.setCurrentPage(appForCaseQo.getPn());
                        pageInfo.setList(list);
                        pageInfo.setPageSize(appForCaseQo.getPs());
                        pageInfo.setTotal(responseEntity.getBody().getTotal());
                        return pageInfo;
                    }
                }
            }
            pageInfo.setCurrentPage(appForCaseQo.getPn());
            pageInfo.setList(null);
            pageInfo.setPageSize(appForCaseQo.getPs());
            pageInfo.setTotal(0L);
        } else {
            if (result != null) {
                log.error("查询投保单列表(案件关联保单时使用) ：" + result.getMsg());
                throw new Exception("查询投保单列表(案件关联保单时使用) 服务器出现问题");
            }
            pageInfo.setCurrentPage(appForCaseQo.getPn());
            pageInfo.setList(null);
            pageInfo.setPageSize(appForCaseQo.getPs());
            pageInfo.setTotal(0L);
        }
        return pageInfo;
    }

    /**
     * 查询被保险人信息(案件关联保单时使用)
     *
     * @param insuredForCaseQo
     * @return
     * @throws Exception
     */
    @Override
    public InsuredForCaseVO insuredForCase(InsuredForCaseQo insuredForCaseQo) throws Exception {
        if (insuredForCaseQo == null) {
            throw new Exception("查询条件不能为空");
        }

        GenericDataResponse<InsuredForCaseVO> result = insClient.insuredForCase(insuredForCaseQo);

        if (result != null && StringUtils.equals(result.getCode(), "0000")) {
            return result.getData();
        } else {
            if (result != null) {
                log.error("查询被保险人信息(案件关联保单时使用) ：" + result.getMsg());
                throw new Exception("查询被保险人信息(案件关联保单时使用) 服务器出现问题");
            }
        }
        return null;
    }

    @Override
    public PostRecordedVo postRecorded(MultipartFile excelFile) {
        //返回的补录结果
        PostRecordedVo postRecordedVo = new PostRecordedVo();
        if (null == excelFile) {
            postRecordedVo.addParserErrorMsg("补录文件不能为空!");
            return postRecordedVo;
        }
        //清单解析结果
        ParserResultPostRecordedVo parserResultVo;
        try {
            ResponseEntity<GenericDataResponse<ParserResultPostRecordedVo>> responseEntity = parserClient.postRecordedAnalysisExcelByFile(excelFile, POST_RECORDED_MODEL_CODE, ReturnType.DETAIL, SaveType.NONE, CHANNEL_CODE);
            //清单解析的错误集合
            //如果清单解析的结果 有错误信息  直接返回报错
            if ((parserResultVo = checkResponse(responseEntity, postRecordedVo.getParserErrorMsgList())) == null) {
                return postRecordedVo;
            }
        } catch (Exception e) {
            postRecordedVo.addParserErrorMsg("清单解析出错!");
            return postRecordedVo;
        }

        //判断最大处理记录数
        List<PostRecordedParserVo> datas = parserResultVo.getDatas();
        if (datas.size() > 1000) {
            postRecordedVo.addParserErrorMsg("补录最大处理记录数为1000!");
            return postRecordedVo;
        }

        List<PostRecordedParserVo> postRecordedParserVoList = Lists.newArrayList();
        for (PostRecordedParserVo postRecordedParserVo : datas) {
            //如果上传的都不为空 即满足预处理 否则舍弃
            if (StringUtils.isNotBlank(postRecordedParserVo.getInsurancePolicyNo())
                    && StringUtils.isNotBlank(postRecordedParserVo.getIssueDate())) {
                postRecordedParserVoList.add(postRecordedParserVo);
            } else {
                //添加到出错app中
                postRecordedVo.addProcessError(postRecordedParserVo.getAppCode());
            }
        }

        //如果没有需要处理的直接返回
        if (CollectionUtils.isEmpty(postRecordedParserVoList)) {
            postRecordedVo.addParserErrorMsg("没有需要补录的数据!");
            return postRecordedVo;
        }
        try {
            //调用投保中心 批量补录接口
            ResponseEntity<GenericListResponse<PostRecordedInsResultVo>> updatePolicyBatchResponse
                    = insClient.postRecordedBatch(JSON.toJSONString(postRecordedParserVoList));
            if (null == updatePolicyBatchResponse || null == updatePolicyBatchResponse.getBody()
                    || CollectionUtils.isEmpty(updatePolicyBatchResponse.getBody().getList())) {
                postRecordedVo.addParserErrorMsg("调用投保中心查询投保单状态出错!");
                return postRecordedVo;
            }
            List<OfflineIssueQo> offlineIssueQos = Lists.newArrayList();
            List<PostRecordedInsResultVo> postRecordedInsResultVos = updatePolicyBatchResponse.getBody().getList();
            for (PostRecordedInsResultVo postRecordedInsResultVo : postRecordedInsResultVos) {
                if (postRecordedInsResultVo.isSucess()) {
                    postRecordedVo.addSuccess();
                    offlineIssueQos.add(createOfflineIssueQo(postRecordedInsResultVo));
                } else {
                    postRecordedVo.addProcessError(postRecordedInsResultVo.getErrorMsg());
                }
            }

            ResponseEntity<GenericDataResponse<Map<String, Object>>> offlineIssueBatchRet
                    = insOrderClient.eduOfflineIssueBatch(offlineIssueQos);
            if (null == offlineIssueBatchRet || null == updatePolicyBatchResponse.getBody()) {
                postRecordedVo.addParserErrorMsg("调用投保中心补录出单信息出错!");
                return postRecordedVo;
            }
        } catch (Exception e) {
            postRecordedVo.addParserErrorMsg("调用投保中心补录出单信息出错!");
            return postRecordedVo;
        }

        return postRecordedVo;
    }

    /**
     * 将PostRecordedInsResultVo 转成 OfflineIssueQo
     *
     * @param postRecordedInsResultVo
     * @return
     */
    private OfflineIssueQo createOfflineIssueQo(PostRecordedInsResultVo postRecordedInsResultVo) {
        OfflineIssueQo offlineIssueQo = new OfflineIssueQo();
        offlineIssueQo.setAppCode(postRecordedInsResultVo.getAppCode());
        offlineIssueQo.setIssueDate(DateUtils.str2Date(postRecordedInsResultVo.getIssueDate(), DateUtils.DATE_FORMAT_YYYY_MM_DD));
        if (StringUtils.isNotBlank(postRecordedInsResultVo.getInsurancePolicyNo())) {
            offlineIssueQo.setPolicyNo(postRecordedInsResultVo.getInsurancePolicyNo());
        }
        return offlineIssueQo;
    }

    /**
     * 处理接口返回结果
     */
    private ParserResultPostRecordedVo checkResponse(ResponseEntity<GenericDataResponse<ParserResultPostRecordedVo>> responseEntity, List<String> errorMsgList) {
        ParserResultPostRecordedVo data;
        if (null == responseEntity.getBody() || (data = responseEntity.getBody().getData()) == null) {
            if (responseEntity.getBody().getMsg() != null) {
                errorMsgList.add(responseEntity.getBody().getMsg());
            } else {
                errorMsgList.add("调用清单解析-上传清单接口失败");
            }
            return null;
        }

        // 接口正常返回错误信息，添加到errorMsgList
        List<Map<String, String>> errorMessages = data.getErrorMessages();
        if (CollectionUtils.isNotEmpty(errorMessages)) {
            for (Map<String, String> errorMessage : errorMessages) {
                String row = errorMessage.get("row");
//                String column = errorMessage.get("column");
                String error = errorMessage.get("errorMessage");
                StringBuilder errorMsg = new StringBuilder();
                if (Integer.valueOf(row) != 0) {
                    errorMsg.append("第").append(row).append("行,");
                }
                errorMsg.append("（").append(error).append("）");
                errorMsgList.add(String.valueOf(errorMsg));
            }
            return null;
        }
        return data;
    }

    public String selectSerialNoByAppCode(String appCode) throws Exception {
        if (appCode == null) {
            throw new Exception("查询条件不能为空");
        }
        String serialNo = insClient.selectSerialNoByAppCode(appCode);
        return serialNo;
    }


    public ResponseData getErrorIssue(String applicationFormCode) throws Exception {
        if (applicationFormCode == null) {
            throw new Exception("查询条件不能为空");
        }
        ResponseData serialNo = insClient.tourIssueFail(applicationFormCode);
        return serialNo;
    }

    @Override
    public ResponseEntity<?> saveApplicationFileInfo(List<ApplicationFileInfoEntity> entities) throws Exception {

        String findCode = "保存清单文件信息_" + System.currentTimeMillis();

        log.info(findCode + "清单保存开始");

        if (entities == null || entities.size() <= 0) {
            throw new Exception("清单信息不能为空");
        }
        int num = 0;
        String currentTime = DateUtils.getCurrentTime();
        for (ApplicationFileInfoEntity e : entities) {

            log.info(findCode + "投保单号：{}, fieldId：{}, fileName：{}, insuredNum：{}",
                    e.getApplicationFormCode(),
                    e.getFileId(),
                    e.getFileName(),
                    e.getInsuredNum());

            Weekend<ApplicationFileInfoEntity> weekend = new Weekend<>(ApplicationFileInfoEntity.class);
            WeekendCriteria<ApplicationFileInfoEntity, Object> criteria = weekend.weekendCriteria();
            criteria.andEqualTo(IS_DELETED, false);
            criteria.andEqualTo("applicationFormCode", e.getApplicationFormCode());
            criteria.andEqualTo("fileId", e.getFileId());
            criteria.andEqualTo("fileName", e.getFileName());
            List<ApplicationFileInfoEntity> files = applicationFileInfoMapper.selectByExample(weekend);
            if (files == null || files.size() <= 0) {
                e.setIsDeleted(false);
                e.setCreateTime(currentTime);
                num += applicationFileInfoMapper.insertSelective(e);

                log.info(findCode + "投保单号：{}, fieldId：{}, fileName：{}, insuredNum：{} 保存成功",
                        e.getApplicationFormCode(),
                        e.getFileId(),
                        e.getFileName(),
                        e.getInsuredNum());
            } else {
                log.info(findCode + "投保单号：{}, fieldId：{}, fileName：{}, insuredNum：{} 已经存在，本次未保存",
                        e.getApplicationFormCode(),
                        e.getFileId(),
                        e.getFileName(),
                        e.getInsuredNum());
            }
        }
        if (num > 0) {
            log.info(findCode + "清单保存完成");
            return GenericListResponse.listAndCount(entities, entities.size());
        } else {
            log.info(findCode + "清单保存失败");
            return GenericListResponse.ng("清单保存失败");
        }
    }

    @Override
    public ResponseEntity<?> getInsuredNumByAppCode(String applicationFormCode) throws Exception {
        Weekend<ApplicationFileInfoEntity> weekend = new Weekend<>(ApplicationFileInfoEntity.class);
        WeekendCriteria<ApplicationFileInfoEntity, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(IS_DELETED, false);
        criteria.andEqualTo("applicationFormCode", applicationFormCode);
        List<ApplicationFileInfoEntity> files = applicationFileInfoMapper.selectByExample(weekend);
        int insuredNum = 0;
        if (files != null && files.size() > 0) {
            for (ApplicationFileInfoEntity entity : files) {
                insuredNum += StringUtils.isNotBlank(entity.getInsuredNum()) ? Integer.valueOf(entity.getInsuredNum()) : 0;
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("applicationFormCode", applicationFormCode);
        result.put("insuredNum", insuredNum);
        return GenericDataResponse.okWithData(result);
    }
}
